#region Summary

// 
// Owner : JackieHan 
// 
// Solution : UpdateSystem
// 
// Project :Project
// 
// File : UploadManager.cs
// 
// CopyRight : Copyright © 2010-2011 Skomart Corporation, All Rights Reserved 
// 
// Summary : 上传管理
// 
// History : 
//			2011-01-07 17:10:19	    Create 
// 

#endregion

#region Using

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.ServiceModel;
using System.Threading;
using System.Windows.Forms;
using Jackie.Utility;
using Jackie.Update.Entities;
using Jackie.Update.IBusiness;

#endregion

namespace Jackie.Update.Publish
{
    /// <summary> 
    /// 上传管理
    /// </summary>
    public class UploadManager
    {
        private readonly UploadForm uploadForm;
        private readonly List<UpdateFileInfo> uploadFiles;
        private readonly Form parentForm;
        private readonly IFileUpDownload fileServiceProxy;
        private readonly string localPath;
        private readonly int uploadLenghtPerTime;
        private readonly string serverPublishDirectory;
        private readonly string newVersion;
        private long totalLength;

        public UploadManager(List<UpdateFileInfo> uploadFiles, Form parentForm, string localPath,
            string serverPublishDirectory,string newVersion)
        {
            var channelFacoty = new ChannelFactory<IFileUpDownload>("fileUpDownloadWcfService");
            fileServiceProxy = channelFacoty.CreateChannel();
            uploadForm = new UploadForm();
            this.uploadFiles = uploadFiles;
            this.parentForm = parentForm;
            this.localPath = localPath;
            this.serverPublishDirectory = serverPublishDirectory;
            this.newVersion = newVersion;
            uploadLenghtPerTime = JackieConvertor.ToIntThrowException(ConfigurationManager.AppSettings["uploadLength"]);
            uploadFiles.ForEach(file => totalLength += file.Length);
        }

        public bool Upload()
        {
            var thread = new Thread(UploadFile);
            thread.Start();
            return uploadForm.ShowDialog(parentForm) == DialogResult.OK;
        }

        private void UploadFile()
        {
            var updateTotal = 0;
            var serverDirectory = Path.Combine(serverPublishDirectory, newVersion);
            foreach (var file in uploadFiles)
            {
                //更新当前上传文件
                UpdateCurrentFile(file.Path);
                var fileLoaclPath = Path.Combine(localPath, file.Path);
                var serverPath = Path.Combine(serverDirectory, file.Path);
                using (var fileStream = new FileStream(fileLoaclPath, FileMode.Open, FileAccess.Read))
                {
                    var fileLength = file.Length;
                    long offset = 0;
                    while (offset < fileLength)
                    {
                        fileStream.Seek(offset, SeekOrigin.Begin);
                        var count = uploadLenghtPerTime;
                        if (fileLength - offset < count)
                            count = (int)(fileLength - offset);
                        var buffer = new byte[count];
                        fileStream.Read(buffer, 0, count);
                        fileServiceProxy.Upload(serverPath, buffer, offset);
                        offset += count;
                        //计算当前文件上传进度
                        var currentPercent = (int)(offset*100 / file.Length);
                        UpdateCurrentPercent(currentPercent);
                        //计算总上传进度
                        updateTotal += count;
                        var totalPercent = (int) (updateTotal*100/totalLength);
                        UpdateTotalPersent(totalPercent);
                    }
                }
            }
            CloseUploadForm();
        }

        private delegate void UpdateCurrentPercentHandler(int percent);
        private void UpdateCurrentPercent(int percent)
        {
            if (uploadForm.pgrCurrent.InvokeRequired)
            {
                var handler = new UpdateCurrentPercentHandler(UpdateCurrentPercent);
                uploadForm.Invoke(handler, percent);
            }
            else
            {
                uploadForm.pgrCurrent.Value = percent;
            }
        }

        private delegate void UpdateCurrentFileHandler(string filePath);
        private void UpdateCurrentFile(string filePath)
        {
            if (uploadForm.lblCurrentFile.InvokeRequired)
            {
                var handler = new UpdateCurrentFileHandler(UpdateCurrentFile);
                uploadForm.Invoke(handler, filePath);
            }
            else
            {
                uploadForm.lblCurrentFile.Text = filePath;
            }
        }

        private delegate void UpdateTotalPersentHandler(int percent);
        private void UpdateTotalPersent(int percent)
        {
            if (uploadForm.pgsTotal.InvokeRequired)
            {
                var handler = new UpdateTotalPersentHandler(UpdateTotalPersent);
                uploadForm.Invoke(handler, percent);
            }
            else
            {
                uploadForm.pgsTotal.Value = percent;
            }
        }

        private delegate void CloseUploadFormHandler();
        private void CloseUploadForm()
        {
            if (uploadForm.InvokeRequired)
            {
                var handler = new CloseUploadFormHandler(CloseUploadForm);
                uploadForm.Invoke(handler);
            }
            else
            {
                uploadForm.DialogResult = DialogResult.OK;
                uploadForm.Close();
            }
        }
    }
}